﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AjaxControlToolkit;
using NotAClue.ComponentModel.DataAnnotations;
using System.Web.UI.WebControls;
using System.Web.DynamicData;
using System.Web.UI;

namespace NotAClue.Web.DynamicData
{
    public static class AjaxControlToolkitExtensions
    {
        /// <summary>
        /// Escape character
        /// </summary>
        private static char escChar = '\\';

        /// <summary>
        /// translatable chars in mask
        /// </summary>
        private static char[] maskChars = new char[]
            {
                '9', // Only a numeric character
                'L', // Only a letter
                '$', // Only a letter or a space
                'C', // Only a custom character ( 'sensitive)
                'A', // Only a letter or a custom character
                'N', // Only a numeric or custom character
                '?', // Any character
                '/', // Date separator
                ':', // Time separator
                '.', // Decimal separator
                ',', // Thousand separator
                //'{', // Initial delimiter for repetition of mask.Masks
                //'}', // Final delimiter for repetition of mask.Masks
            };

        /// <summary>
        /// Setups the mask.
        /// </summary>
        /// <param name="maskedEditExtender">The masked edit extender.</param>
        /// <param name="column">The column.</param>
        public static void SetupMask(this MaskedEditExtender maskedEditExtender, MetaColumn column)
        {
            var mask = column.GetAttribute<EditMaskAttribute>();
            if (mask != null)
            {
                maskedEditExtender.Enabled = true;
                maskedEditExtender.Mask = mask.Mask;
            }
        }

        /// <summary>
        /// Sets the mask.
        /// </summary>
        /// <param name="textControl">The control.</param>
        /// <param name="column">The column.</param>
        /// <param name="fieldValueString">The field value string.</param>
        public static void SetMask(this ITextControl textControl, MetaColumn column, String fieldValueString)
        {
            var mask = column.GetAttribute<EditMaskAttribute>();
            if (mask != null)
                textControl.Text = fieldValueString.ToMaskedString(mask.Mask);
            else
                textControl.Text = fieldValueString;
        }

        public static String ToMaskedString(this String value, MetaColumn column)
        {
            var mask = column.GetAttribute<EditMaskAttribute>();
            if (mask != null)
            {
                // return an empty string for an empty string
                if (String.IsNullOrEmpty(value))
                    return String.Empty;

                var sb = new StringBuilder();
                var i = 0;
                for (int c = 0; c < mask.Mask.Length; c++)
                {
                    // exit loop if string is short
                    if (i == value.Length)
                        break;

                    if (mask.Mask[c] == escChar)
                    {
                        c++;
                        sb.Append(mask.Mask[c]);
                    }
                    else if (maskChars.Contains(mask.Mask[c]))
                    {
                        sb.Append(value[i]);
                        i++;
                    }
                    else
                        sb.Append(mask.Mask[c]);
                }

                return sb.ToString();
            }
            return value;
        }

        /// <summary>
        /// Toes the masked string.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="mask">The mask.</param>
        /// <returns>the masked string</returns>
        public static String ToMaskedString(this String value, String mask)
        {
            // return an empty string for an empty string
            if (String.IsNullOrEmpty(value))
                return String.Empty;

            var sb = new StringBuilder();
            var i = 0;
            for (int c = 0; c < mask.Length; c++)
            {
                // exit loop if string is short
                if (i == value.Length)
                    break;

                if (mask[c] == escChar)
                {
                    c++;
                    sb.Append(mask[c]);
                }
                else if (maskChars.Contains(mask[c]))
                {
                    sb.Append(value[i]);
                    i++;
                }
                else
                    sb.Append(mask[c]);
            }

            return sb.ToString();
        }
    }
}
